//
//  ZYActiveThread.m
//  OC_Principle
//
//  Created by wangzhipan on 2025/2/13.
//

#import "ZYActiveThread.h"
#import "ZYProxy.h"

@interface ZYThread : NSThread

@end

@implementation ZYThread

- (void)dealloc
{
    NSLog(@"%s", __func__);
}

@end

@interface ZYActiveThread()
@property (nonatomic, strong, nullable) ZYThread *innerThread;

@property (nonatomic, assign) BOOL isStarting;
@end

@implementation ZYActiveThread

- (instancetype)init
{
    if (self = [super init]) {
        self.isStarting = YES;
        [self p_runThread];
    }
    return self;
}

- (void)dealloc
{
    NSLog(@"%s", __func__);
    [self stop];
}

/// 在当前子线程执行task
- (void)executeTask:(Block_task)task
{
    if (!self.isStarting || !task) {
        return;
    }
    [self performSelector:@selector(p_doTask:) onThread:self.innerThread withObject:task waitUntilDone:NO];
}

- (void)stop
{
    [self performSelector:@selector(p_stop) onThread:self.innerThread withObject:nil waitUntilDone:YES];
}


- (void)p_doTask:(Block_task)task
{
    task ? task() : nil;
}

- (void)p_runThread
{
   /* 消息转发，必须手动调用stop 停止才能释放内存
    ZYProxy *proxy = [[ZYProxy alloc] initWithTarget:self];
    self.innerThread = [[ZYThread alloc] initWithTarget:proxy selector:@selector(p_stayLife) object:nil];
    [self.innerThread start];
    */
    
    //block + weak，就无需外界手动调用stop
    __weak typeof(self) weakSelf = self;
    self.innerThread = [[ZYThread alloc] initWithBlock:^{
        [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
        
        while (weakSelf.isStarting) {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
        NSLog(@"%s", __func__);
    }];
    [self.innerThread start];
}

- (void)p_stayLife
{
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    
    while (self.isStarting) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
    
    NSLog(@"%s", __func__);
}

- (void)p_stop
{
    self.isStarting = NO;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.innerThread = nil;
}

@end
